package com.sun.gis.tools.wmts;


import com.sun.gis.tools.sld.SldRenderer;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.FeatureLayer;
import org.geotools.map.MapContent;
import org.geotools.ows.wmts.WebMapTileServer;
import org.geotools.ows.wmts.map.WMTSMapLayer;
import org.geotools.ows.wmts.model.WMTSCapabilities;
import org.geotools.ows.wmts.model.WMTSLayer;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.Style;
import org.geotools.swing.JMapFrame;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import java.util.List;


/**
 * 使用MapContent加载GeoServer发布的标准WMTS服务
 *
 * @author sunbt
 * @date 2023/8/27 20:13
 */
public class WMTSLoader {


    public static void test() {
        // 定义你感兴趣的图层名称
        String layerName = "division:city";

        // SLD (样式图层描述符) 文件的路径
        String path = "/Users/sungang/Documents/code/gitee/gis-server/data/sld/model_1.1.0_320205.sld";

        // 从SLD文件加载样式
        Style style = SldRenderer.readSldReturnOne(path);

        // 您想要可视化的shapefile的路径
        File file = new File("/Users/sungang/Documents/code/gitee/gis-server/data/shapefile/320205_county.shp");
        URL shapefileURL = null;

        try {
            // 将shapefile路径转换为URL
            shapefileURL = file.toURI().toURL();

            // 将shapefile加载到数据存储中
            ShapefileDataStore dataStore = new ShapefileDataStore(shapefileURL);
            SimpleFeatureSource featureSource = dataStore.getFeatureSource();
            ReferencedEnvelope bound = featureSource.getBounds();

            // WMTS (Web地图瓦片服务)能力请求的URL
            URL url = new URL("http://sunbt.ltd:8080/geoserver/gwc/service/wmts?REQUEST=GetCapabilities");

            // 连接到WMTS服务
            WebMapTileServer wmts = new WebMapTileServer(url);
            WMTSCapabilities capabilities = wmts.getCapabilities();

            // 从WMTS服务检索可用图层的列表
            List<WMTSLayer> layerList = capabilities.getLayerList();

            // 查找名为 "division:city" 的图层
            WMTSLayer wmtsLayer = null;
            for (WMTSLayer layer : layerList) {
                if (layerName.equals(layer.getName())) {
                    wmtsLayer = layer;
                    break;
                }
            }

            // 如果找到图层，则加载并显示它
            if (wmtsLayer != null) {
                WMTSMapLayer mapLayer = new WMTSMapLayer(wmts, wmtsLayer);

                // 创建一个新的地图内容，以添加图层
                MapContent mapContent = new MapContent();
                mapContent.addLayer(mapLayer);

                ReferencedEnvelope bounds = mapLayer.getBounds();

                // 定义地图视图的中心坐标
                double lon = 119.783;
                double lat = 32.792;

                // 根据指定的缩放级别设置地图视图边界
                int zoomLevel = 6;
                double span = 180.0 / Math.pow(2, zoomLevel);
                ReferencedEnvelope envelope = new ReferencedEnvelope(
                        lon - span, lon + span, lat - span, lat + span, DefaultGeographicCRS.WGS84);

                // 使用shapefile和从SLD加载的样式添加一个矢量图层
                FeatureLayer layer = new FeatureLayer(featureSource, style);
                mapContent.addLayer(layer);
                mapContent.getViewport().setBounds(bound);

                // 使用JMapFrame在屏幕上显示地图
                JMapFrame.showMap(mapContent);

                // 输出图像 (PNG) 的路径
                String photoPath = "/Users/sungang/Documents/code/gitee/gis-server/data/output/wmts/wmts-shapefile.png";
                rendererToPng(mapContent, bound, photoPath);
            } else {
                System.out.println("图层 " + layerName + " 未找到.");
            }

        } catch (Exception e) {
            // 在执行过程中处理任何可能发生的异常
            e.printStackTrace();
        }
    }

    /**
     * 将地图视图渲染到PNG图像文件。
     *
     * @param mapContent mapContent：要渲染的地图内容。
     * @param bound      bound：要渲染的区域的边界。
     * @param photoPath  photoPath：输出PNG将保存的文件路径。
     */
    public static void rendererToPng(MapContent mapContent, ReferencedEnvelope bound, String photoPath) {

        try {
            // 初始化一个新的渲染器并设置其地图内容
            StreamingRenderer renderer = new StreamingRenderer();
            renderer.setMapContent(mapContent);

            // 定义输出图像的尺寸
            int imageWidth = 800;
            int imageHeight = 600;
            BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
            Graphics2D graphics = image.createGraphics();

            // 将图像背景设置为透明
            graphics.setComposite(AlphaComposite.Clear);
            graphics.fillRect(0, 0, imageWidth, imageHeight);
            graphics.setComposite(AlphaComposite.SrcOver);

            // 在图像上渲染地图
            Rectangle imageBounds = new Rectangle(0, 0, imageWidth, imageHeight);
            renderer.paint(graphics, imageBounds, bound);

            // 将渲染的图像保存为PNG文件
            File pngFile = new File(photoPath);
            ImageIO.write(image, "png", pngFile);

            System.out.println("输出文件: " + pngFile.getAbsolutePath());
        } catch (Exception e) {
            // 在渲染过程中处理可能出现的任何异常
            e.printStackTrace();
        }
    }



    public static void main(String[] args) {
        test();
    }


}